home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Synth / ADnote.C next >
C/C++ Source or Header  |  2005-03-14  |  36KB  |  985 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   ADnote.C - The "additive" synthesizer
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20. */
  21.  
  22. #include <math.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25.  
  26.  
  27. #include "../globals.h"
  28. #include "../Misc/Util.h"
  29. #include "ADnote.h"
  30.  
  31.  
  32. ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_){
  33.     ready=0;
  34.     
  35.     tmpwave=new REALTYPE [SOUND_BUFFER_SIZE];
  36.     bypassl=new REALTYPE [SOUND_BUFFER_SIZE];
  37.     bypassr=new REALTYPE [SOUND_BUFFER_SIZE];
  38.  
  39.     partparams=pars;
  40.     ctl=ctl_;
  41.     portamento=portamento_;
  42.     midinote=midinote_;
  43.     NoteEnabled=ON;
  44.     basefreq=freq;
  45.     if (velocity>1.0) velocity=1.0;
  46.     this->velocity=velocity;  
  47.     time=0.0;
  48.     stereo=pars->GlobalPar.PStereo;
  49.  
  50.     NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType
  51.         ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune);
  52.     bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier();
  53.     
  54.     if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND;
  55.     else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0;
  56.     
  57.  
  58.     NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq
  59.         pars->GlobalPar.PFilterVelocityScale/127.0*6.0*  //velocity sensing
  60.         (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1);
  61.  
  62.     if (pars->GlobalPar.PPunchStrength!=0) {
  63.         NoteGlobalPar.Punch.Enabled=1;
  64.     NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0
  65.     NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0)
  66.         *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) );
  67.     REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms
  68.     REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0);
  69.     NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch);
  70.     } else NoteGlobalPar.Punch.Enabled=0;
  71.  
  72.     for (int nvoice=0;nvoice<NUM_VOICES;nvoice++){
  73.     pars->VoicePar[nvoice].OscilSmp->newrandseed(rand());
  74.     NoteVoicePar[nvoice].OscilSmp=NULL;
  75.     NoteVoicePar[nvoice].FMSmp=NULL;
  76.     NoteVoicePar[nvoice].VoiceOut=NULL;
  77.  
  78.     NoteVoicePar[nvoice].FMVoice=-1;
  79.     
  80.     if (pars->VoicePar[nvoice].Enabled==0) {
  81.         NoteVoicePar[nvoice].Enabled=OFF;
  82.         continue; //the voice is disabled
  83.     };
  84.  
  85.     NoteVoicePar[nvoice].Enabled=ON;
  86.     NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq;
  87.     NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET;
  88.     
  89.     //use the Globalpars.detunetype if the detunetype is 0
  90.     if (pars->VoicePar[nvoice].PDetuneType!=0){
  91.             NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType
  92.         ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune
  93.             NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType
  94.         ,0,pars->VoicePar[nvoice].PDetune);//fine detune
  95.     } else { 
  96.         NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType
  97.         ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune
  98.         NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType
  99.         ,0,pars->VoicePar[nvoice].PDetune);//fine detune
  100.     };
  101.     if (pars->VoicePar[nvoice].PFMDetuneType!=0){ 
  102.         NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType
  103.         ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune);
  104.     } else {
  105.         NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType
  106.         ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune);
  107.     };
  108.  
  109.         oscposhi[nvoice]=0;oscposlo[nvoice]=0.0;
  110.         oscposhiFM[nvoice]=0;oscposloFM[nvoice]=0.0;
  111.     
  112.     NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point
  113.  
  114.     //Get the voice's oscil or external's voice oscil
  115.     int vc=nvoice; 
  116.     if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil;
  117.     if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand());
  118.     oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),
  119.                      pars->VoicePar[nvoice].Presonance);
  120.  
  121.     //I store the first elments to the last position for speedups
  122.     for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].OscilSmp[i];
  123.  
  124.     oscposhi[nvoice]+=(int)((pars->VoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
  125.     oscposhi[nvoice]%=OSCIL_SIZE;
  126.     
  127.     
  128.     NoteVoicePar[nvoice].FreqLfo=NULL;
  129.     NoteVoicePar[nvoice].FreqEnvelope=NULL;
  130.  
  131.     NoteVoicePar[nvoice].AmpLfo=NULL;
  132.     NoteVoicePar[nvoice].AmpEnvelope=NULL;
  133.     
  134.     NoteVoicePar[nvoice].VoiceFilter=NULL;
  135.     NoteVoicePar[nvoice].FilterEnvelope=NULL;
  136.     NoteVoicePar[nvoice].FilterLfo=NULL;
  137.  
  138.     NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq();
  139.         NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass;
  140.     
  141.     switch(pars->VoicePar[nvoice].PFMEnabled){
  142.         case 1:NoteVoicePar[nvoice].FMEnabled=MORPH;break;
  143.         case 2:NoteVoicePar[nvoice].FMEnabled=RING_MOD;break;
  144.         case 3:NoteVoicePar[nvoice].FMEnabled=PHASE_MOD;break;
  145.         case 4:NoteVoicePar[nvoice].FMEnabled=FREQ_MOD;break;
  146.         case 5:NoteVoicePar[nvoice].FMEnabled=PITCH_MOD;break;
  147.         default:NoteVoicePar[nvoice].FMEnabled=NONE;
  148.     };
  149.  
  150.     NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice;
  151.     NoteVoicePar[nvoice].FMFreqEnvelope=NULL;
  152.     NoteVoicePar[nvoice].FMAmpEnvelope=NULL;
  153.  
  154.     //Compute the Voice's modulator volume (incl. damping)
  155.     REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0);
  156.     switch (NoteVoicePar[nvoice].FMEnabled){
  157.         case PHASE_MOD:fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0);
  158.                NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0;
  159.                break;
  160.         case FREQ_MOD:NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0;
  161.                   break;
  162.     //    case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//???????????
  163.     //              break;
  164.         default:if (fmvoldamp>1.0) fmvoldamp=1.0;
  165.                 NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp;
  166.     };
  167.  
  168.     //Voice's modulator velocity sensing
  169.     NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
  170.  
  171.     FMoldsmp[nvoice]=0.0;//this is for FM (integration)
  172.  
  173.     firsttick[nvoice]=1;
  174.     NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE);
  175.   };
  176.  
  177.     initparameters();
  178.     ready=1;
  179. };
  180.  
  181.  
  182. /*
  183.  * Kill a voice of ADnote
  184.  */
  185. void ADnote::KillVoice(int nvoice){
  186.   
  187.     delete (NoteVoicePar[nvoice].OscilSmp);
  188.  
  189.     if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) delete(NoteVoicePar[nvoice].FreqEnvelope);
  190.     NoteVoicePar[nvoice].FreqEnvelope=NULL;
  191.     
  192.     if (NoteVoicePar[nvoice].FreqLfo!=NULL) delete(NoteVoicePar[nvoice].FreqLfo);
  193.     NoteVoicePar[nvoice].FreqLfo=NULL;
  194.  
  195.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].AmpEnvelope);
  196.     NoteVoicePar[nvoice].AmpEnvelope=NULL;
  197.     
  198.     if (NoteVoicePar[nvoice].AmpLfo!=NULL) delete (NoteVoicePar[nvoice].AmpLfo);
  199.     NoteVoicePar[nvoice].AmpLfo=NULL;
  200.  
  201.     if (NoteVoicePar[nvoice].VoiceFilter!=NULL) delete (NoteVoicePar[nvoice].VoiceFilter);
  202.     NoteVoicePar[nvoice].VoiceFilter=NULL;
  203.  
  204.     if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) delete (NoteVoicePar[nvoice].FilterEnvelope);
  205.     NoteVoicePar[nvoice].FilterEnvelope=NULL;
  206.  
  207.     if (NoteVoicePar[nvoice].FilterLfo!=NULL) delete (NoteVoicePar[nvoice].FilterLfo);
  208.     NoteVoicePar[nvoice].FilterLfo=NULL;
  209.  
  210.     if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMFreqEnvelope);
  211.     NoteVoicePar[nvoice].FMFreqEnvelope=NULL;
  212.     
  213.     if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMAmpEnvelope);
  214.     NoteVoicePar[nvoice].FMAmpEnvelope=NULL;
  215.     
  216.     if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) delete NoteVoicePar[nvoice].FMSmp;
  217.     
  218.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) 
  219.     for (int i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;//do not delete, yet: perhaps is used by another voice
  220.  
  221.     NoteVoicePar[nvoice].Enabled=OFF;
  222. };
  223.  
  224. /*
  225.  * Kill the note
  226.  */
  227. void ADnote::KillNote(){
  228.     int nvoice;
  229.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  230.     if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice);
  231.  
  232.     //delete VoiceOut
  233.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) delete(NoteVoicePar[nvoice].VoiceOut);
  234.     NoteVoicePar[nvoice].VoiceOut=NULL;
  235.     };
  236.     
  237.     delete (NoteGlobalPar.FreqEnvelope);
  238.     delete (NoteGlobalPar.FreqLfo);
  239.     delete (NoteGlobalPar.AmpEnvelope);
  240.     delete (NoteGlobalPar.AmpLfo);
  241.     delete (NoteGlobalPar.GlobalFilterL);
  242.     if (stereo!=0) delete (NoteGlobalPar.GlobalFilterR);
  243.     delete (NoteGlobalPar.FilterEnvelope);
  244.     delete (NoteGlobalPar.FilterLfo);
  245.     
  246.     NoteEnabled=OFF;
  247. };
  248.  
  249. ADnote::~ADnote(){
  250.     if (NoteEnabled==ON) KillNote();
  251.     delete [] tmpwave;
  252.     delete [] bypassl;
  253.     delete [] bypassr;
  254. };
  255.  
  256.  
  257. /*
  258.  * Init the parameters
  259.  */
  260. void ADnote::initparameters(){
  261.     int nvoice,i,tmp[NUM_VOICES];
  262.  
  263.     // Global Parameters
  264.     NoteGlobalPar.FreqEnvelope=new Envelope(partparams->GlobalPar.FreqEnvelope,basefreq);
  265.     NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq);
  266.     
  267.     NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq);
  268.     NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq);
  269.  
  270.     NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB
  271.         *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing
  272.  
  273.     NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output
  274.     globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
  275.  
  276.     NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter);
  277.     if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter);
  278.     
  279.     NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq);
  280.     NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq);
  281.     NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq();
  282.     NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq);
  283.     
  284.     // Forbids the Modulation Voice to be greater or equal than voice
  285.     for (i=0;i<NUM_VOICES;i++) if (NoteVoicePar[i].FMVoice>=i) NoteVoicePar[i].FMVoice=-1;
  286.  
  287.     // Voice Parameter init
  288.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  289.         if (NoteVoicePar[nvoice].Enabled==0) continue;
  290.  
  291.     NoteVoicePar[nvoice].noisetype=partparams->VoicePar[nvoice].Type;
  292.     /* Voice Amplitude Parameters Init */
  293.     NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB
  294.         *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity
  295.         
  296.     if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume;
  297.  
  298.     if (partparams->VoicePar[nvoice].PPanning==0) 
  299.         NoteVoicePar[nvoice].Panning=RND;// random panning
  300.     else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0;
  301.  
  302.     newamplitude[nvoice]=1.0;
  303.     if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) {
  304.         NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq);
  305.         NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample
  306.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
  307.         };
  308.  
  309.     if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0){
  310.         NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq);
  311.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout();
  312.     };
  313.  
  314.     /* Voice Frequency Parameters Init */
  315.     if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0)
  316.          NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq);
  317.  
  318.     if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq);
  319.  
  320.     /* Voice Filter Parameters Init */
  321.     if (partparams->VoicePar[nvoice].PFilterEnabled!=0){
  322.         NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter);
  323.     };
  324.  
  325.     if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0)
  326.         NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq);
  327.     
  328.     if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0)
  329.         NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq);
  330.     
  331.     NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq);
  332.     
  333.     /* Voice Modulation Parameters Init */
  334.     if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)){
  335.        partparams->VoicePar[nvoice].FMSmp->newrandseed(rand());
  336.         NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];
  337.  
  338.        //Perform Anti-aliasing only on MORPH or RING MODULATION
  339.  
  340.        int vc=nvoice; 
  341.             if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil;
  342.  
  343.        REALTYPE tmp=1.0;
  344.        if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)||
  345.         (NoteVoicePar[nvoice].FMEnabled==MORPH)||
  346.         (NoteVoicePar[nvoice].FMEnabled==RING_MOD)){
  347.         tmp=getFMvoicebasefreq(nvoice);
  348.         };
  349.        if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand());
  350.        
  351.        oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE;
  352.        for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].FMSmp[i];
  353.        oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
  354.        oscposhiFM[nvoice]%=OSCIL_SIZE;
  355.     };
  356.  
  357.     if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)
  358.         NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq);
  359.  
  360.     FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
  361.  
  362.     if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0){
  363.         NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq);
  364.         FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  365.     };
  366.     };
  367.  
  368.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  369.     for (i=nvoice+1;i<NUM_VOICES;i++) tmp[i]=0;
  370.     for (i=nvoice+1;i<NUM_VOICES;i++) 
  371.     if ((NoteVoicePar[i].FMVoice==nvoice)&&(tmp[i]==0)){
  372.             NoteVoicePar[nvoice].VoiceOut=new REALTYPE[SOUND_BUFFER_SIZE];
  373.         tmp[i]=1;
  374.     };
  375.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;
  376.     };
  377. };
  378.  
  379.  
  380.  
  381. /*
  382.  * Computes the frequency of an oscillator
  383.  */
  384. void ADnote::setfreq(int nvoice,REALTYPE freq){
  385.     REALTYPE speed;
  386.     freq=fabs(freq);
  387.     speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
  388.     if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
  389.  
  390.     F2I(speed,oscfreqhi[nvoice]);
  391.     oscfreqlo[nvoice]=speed-floor(speed);
  392. };   
  393.  
  394. /*
  395.  * Computes the frequency of an modullator oscillator
  396.  */
  397. void ADnote::setfreqFM(int nvoice,REALTYPE freq){
  398.     REALTYPE speed;
  399.     freq=fabs(freq);
  400.     speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
  401.     if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
  402.  
  403.     F2I(speed,oscfreqhiFM[nvoice]);
  404.     oscfreqloFM[nvoice]=speed-floor(speed);
  405. };
  406.  
  407. /*
  408.  * Get Voice base frequency
  409.  */
  410. REALTYPE ADnote::getvoicebasefreq(int nvoice){
  411.     REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+
  412.         NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+
  413.     NoteGlobalPar.Detune/100.0;
  414.  
  415.     if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0));
  416.     else {//the fixed freq is enabled
  417.         REALTYPE fixedfreq=440.0;
  418.         int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET;
  419.         if (fixedfreqET!=0) {//if the frequency varies according the keyboard note 
  420.         REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
  421.         if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp);
  422.             else fixedfreq*=pow(3.0,tmp);
  423.         };
  424.         return(fixedfreq*pow(2.0,detune/12.0));
  425.     };
  426. };
  427.  
  428. /*
  429.  * Get Voice's Modullator base frequency
  430.  */
  431. REALTYPE ADnote::getFMvoicebasefreq(int nvoice){
  432.     REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0;
  433.     return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
  434. };
  435.  
  436. /*
  437.  * Computes all the parameters for each tick
  438.  */
  439. void ADnote::computecurrentparameters(){
  440.     int nvoice;
  441.     REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch;
  442.     globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+
  443.     NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod);
  444.     globaloldamplitude=globalnewamplitude;
  445.     globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
  446.     
  447.     globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout()
  448.                       +NoteGlobalPar.FilterCenterPitch;
  449.               
  450.     REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq
  451.             +NoteGlobalPar.FilterFreqTracking;
  452.     
  453.     tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq);
  454.     
  455.     REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq;
  456.     NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq);
  457.     if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq);
  458.  
  459.     //compute the portamento, if it is used by this note
  460.     REALTYPE portamentofreqrap=1.0;    
  461.     if (portamento!=0){//this voice use portamento
  462.     portamentofreqrap=ctl->portamento.freqrap;
  463.     if (ctl->portamento.used==0){//the portamento has finished
  464.         portamento=0;//this note is no longer "portamented"
  465.     };
  466.     };
  467.     
  468.     //compute parameters for all voices
  469.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  470.     if (NoteVoicePar[nvoice].Enabled!=ON) continue;
  471.     NoteVoicePar[nvoice].DelayTicks-=1;
  472.     if (NoteVoicePar[nvoice].DelayTicks>0) continue;
  473.         
  474.     /*******************/
  475.     /* Voice Amplitude */
  476.     /*******************/
  477.         oldamplitude[nvoice]=newamplitude[nvoice];
  478.     newamplitude[nvoice]=1.0;
  479.  
  480.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL)
  481.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();        
  482.  
  483.     if (NoteVoicePar[nvoice].AmpLfo!=NULL) 
  484.             newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout();        
  485.  
  486.     /****************/
  487.     /* Voice Filter */
  488.     /****************/
  489.     if (NoteVoicePar[nvoice].VoiceFilter!=NULL){
  490.         filterpitch=NoteVoicePar[nvoice].FilterCenterPitch;  
  491.  
  492.         if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) 
  493.         filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout();
  494.  
  495.         if (NoteVoicePar[nvoice].FilterLfo!=NULL) 
  496.         filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout();
  497.         
  498.         filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking;
  499.         filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq);
  500.         
  501.         NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq);
  502.     };
  503.  
  504.     if (NoteVoicePar[nvoice].noisetype==0){//compute only if the voice isn't noise
  505.  
  506.         /*******************/
  507.         /* Voice Frequency */
  508.         /*******************/
  509.         voicepitch=0.0;
  510.         if (NoteVoicePar[nvoice].FreqLfo!=NULL) 
  511.         voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0
  512.                      *ctl->bandwidth.relbw;
  513.  
  514.         if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0;
  515.         voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency
  516.         voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller
  517.         setfreq(nvoice,voicefreq*portamentofreqrap);    
  518.  
  519.         /***************/
  520.         /*  Modulator */
  521.         /***************/
  522.         if (NoteVoicePar[nvoice].FMEnabled!=NONE){
  523.         FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0;
  524.         if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100;
  525.             FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap;
  526.         setfreqFM(nvoice,FMfreq);
  527.  
  528.         FMoldamplitude[nvoice]=FMnewamplitude[nvoice];
  529.         FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
  530.         if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) 
  531.                 FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  532.         };
  533.     };
  534.     
  535.     };
  536.     time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
  537. };
  538.  
  539.  
  540. /*
  541.  * Fadein in a way that removes clicks but keep sound "punchy"
  542.  */
  543. inline void ADnote::fadein(REALTYPE *smps){
  544.     int zerocrossings=0;
  545.     for (int i=1;i<SOUND_BUFFER_SIZE;i++)
  546.     if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings
  547.  
  548.     REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0;
  549.     if (tmp<8.0) tmp=8.0;
  550.  
  551.     int n;
  552.     F2I(tmp,n);//how many samples is the fade-in    
  553.     if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
  554.     for (int i=0;i<n;i++) {//fade-in
  555.     REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5;
  556.     smps[i]*=tmp;
  557.     };
  558. };
  559.  
  560. /*
  561.  * Computes the Oscillator (Without Modulation) - LinearInterpolation
  562.  */
  563. inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice){    
  564.     int i,poshi;
  565.     REALTYPE poslo;
  566.  
  567.     poshi=oscposhi[nvoice];
  568.     poslo=oscposlo[nvoice];
  569.     REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp;
  570.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  571.     tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
  572.     poslo+=oscfreqlo[nvoice];
  573.     if (poslo>=1.0) {
  574.             poslo-=1.0;    
  575.         poshi++;
  576.     };
  577.         poshi+=oscfreqhi[nvoice];    
  578.         poshi&=OSCIL_SIZE-1;
  579.     };
  580.     oscposhi[nvoice]=poshi;
  581.     oscposlo[nvoice]=poslo;
  582. };
  583.  
  584.  
  585.  
  586. /*
  587.  * Computes the Oscillator (Without Modulation) - CubicInterpolation
  588.  *
  589.  The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
  590. inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){    
  591.     int i,poshi;
  592.     REALTYPE poslo;
  593.  
  594.     poshi=oscposhi[nvoice];
  595.     poslo=oscposlo[nvoice];
  596.     REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp;
  597.     REALTYPE xm1,x0,x1,x2,a,b,c;
  598.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  599.     xm1=smps[poshi];
  600.     x0=smps[poshi+1];
  601.     x1=smps[poshi+2];
  602.     x2=smps[poshi+3];
  603.     a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
  604.     b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
  605.     c = (x1 - xm1) / 2.0;
  606.     tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
  607.     printf("a\n");
  608.     //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
  609.     poslo+=oscfreqlo[nvoice];
  610.     if (poslo>=1.0) {
  611.             poslo-=1.0;    
  612.         poshi++;
  613.     };
  614.         poshi+=oscfreqhi[nvoice];    
  615.         poshi&=OSCIL_SIZE-1;
  616.     };
  617.     oscposhi[nvoice]=poshi;
  618.     oscposlo[nvoice]=poslo;
  619. };
  620. */
  621. /*
  622.  * Computes the Oscillator (Morphing)
  623.  */
  624. inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice){    
  625.     int i;
  626.     REALTYPE amp;
  627.     ComputeVoiceOscillator_LinearInterpolation(nvoice);    
  628.     if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
  629.     if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
  630.     
  631.     if (NoteVoicePar[nvoice].FMVoice>=0){
  632.     //if I use VoiceOut[] as modullator
  633.     int FMVoice=NoteVoicePar[nvoice].FMVoice;
  634.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  635.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  636.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  637.         tmpwave[i]=tmpwave[i]*(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
  638.         };
  639.     } else {
  640.     int poshiFM=oscposhiFM[nvoice];
  641.     REALTYPE posloFM=oscposloFM[nvoice];
  642.  
  643.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  644.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  645.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  646.         tmpwave[i]=tmpwave[i]*(1.0-amp)+amp
  647.                   *(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1-posloFM)
  648.                +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
  649.         posloFM+=oscfreqloFM[nvoice];
  650.         if (posloFM>=1.0) {
  651.             posloFM-=1.0;    
  652.         poshiFM++;
  653.         };
  654.             poshiFM+=oscfreqhiFM[nvoice];    
  655.             poshiFM&=OSCIL_SIZE-1;
  656.     };
  657.     oscposhiFM[nvoice]=poshiFM;
  658.     oscposloFM[nvoice]=posloFM;
  659.     };
  660. };
  661.  
  662. /*
  663.  * Computes the Oscillator (Ring Modulation)
  664.  */
  665. inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice){    
  666.     int i;
  667.     REALTYPE amp;
  668.     ComputeVoiceOscillator_LinearInterpolation(nvoice);    
  669.     if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
  670.     if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
  671.     if (NoteVoicePar[nvoice].FMVoice>=0){
  672.     // if I use VoiceOut[] as modullator
  673.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  674.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  675.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  676.         int FMVoice=NoteVoicePar[nvoice].FMVoice;
  677.         for (i=0;i<SOUND_BUFFER_SIZE;i++) 
  678.          tmpwave[i]*=(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
  679.     };
  680.     } else {
  681.     int poshiFM=oscposhiFM[nvoice];
  682.     REALTYPE posloFM=oscposloFM[nvoice];
  683.  
  684.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  685.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  686.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  687.         tmpwave[i]*=( NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
  688.                      +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM)*amp
  689.              +(1.0-amp);
  690.         posloFM+=oscfreqloFM[nvoice];
  691.         if (posloFM>=1.0) {
  692.             posloFM-=1.0;    
  693.         poshiFM++;
  694.         };
  695.             poshiFM+=oscfreqhiFM[nvoice];    
  696.             poshiFM&=OSCIL_SIZE-1;
  697.     };
  698.     oscposhiFM[nvoice]=poshiFM;
  699.     oscposloFM[nvoice]=posloFM;
  700.     };
  701. };
  702.  
  703.  
  704.  
  705. /*
  706.  * Computes the Oscillator (Phase Modulation or Frequency Modulation)
  707.  */
  708. inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode){
  709.     int carposhi;
  710.     int i,FMmodfreqhi;
  711.     REALTYPE FMmodfreqlo,carposlo;
  712.     
  713.     if (NoteVoicePar[nvoice].FMVoice>=0){
  714.     //if I use VoiceOut[] as modulator
  715.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i];
  716.     } else {
  717.     //Compute the modulator and store it in tmpwave[]
  718.     int poshiFM=oscposhiFM[nvoice];
  719.     REALTYPE posloFM=oscposloFM[nvoice];
  720.  
  721.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  722.         tmpwave[i]=(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
  723.                    +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
  724.         posloFM+=oscfreqloFM[nvoice];
  725.         if (posloFM>=1.0) {
  726.         posloFM=fmod(posloFM,1.0);
  727.         poshiFM++;
  728.         };
  729.             poshiFM+=oscfreqhiFM[nvoice];    
  730.             poshiFM&=OSCIL_SIZE-1;
  731.     };
  732.     oscposhiFM[nvoice]=poshiFM;
  733.     oscposloFM[nvoice]=posloFM;
  734.     };
  735.     // Amplitude interpolation
  736.     if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])){
  737.           for (i=0;i<SOUND_BUFFER_SIZE;i++){
  738.         tmpwave[i]*=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  739.                       ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  740.         };
  741.     } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=FMnewamplitude[nvoice];
  742.  
  743.  
  744.     //normalize makes all sample-rates, oscil_sizes toproduce same sound    
  745.     if (FMmode!=0){//Frequency modulation
  746.     REALTYPE normalize=OSCIL_SIZE/262144.0*44100.0/(REALTYPE)SAMPLE_RATE;
  747.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  748.         FMoldsmp[nvoice]=fmod(FMoldsmp[nvoice]+tmpwave[i]*normalize,OSCIL_SIZE);
  749.         tmpwave[i]=FMoldsmp[nvoice];
  750.     };
  751.     } else {//Phase modulation 
  752.     REALTYPE normalize=OSCIL_SIZE/262144.0;
  753.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=normalize;
  754.     };
  755.  
  756.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  757.     F2I(tmpwave[i],FMmodfreqhi);
  758.     FMmodfreqlo=fmod(tmpwave[i]+0.0000000001,1.0); 
  759.     if (FMmodfreqhi<0) FMmodfreqlo++;
  760.     
  761.     //carrier
  762.     carposhi=oscposhi[nvoice]+FMmodfreqhi;
  763.     carposlo=oscposlo[nvoice]+FMmodfreqlo;
  764.  
  765.     if (carposlo>=1.0) {
  766.         carposhi++;
  767.         carposlo=fmod(carposlo,1.0);
  768.     };
  769.     carposhi&=(OSCIL_SIZE-1);    
  770.         
  771.     tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo)
  772.               +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo;
  773.  
  774.     oscposlo[nvoice]+=oscfreqlo[nvoice];
  775.     if (oscposlo[nvoice]>=1.0) {
  776.             oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0);    
  777.         oscposhi[nvoice]++;
  778.     };
  779.             
  780.         oscposhi[nvoice]+=oscfreqhi[nvoice];    
  781.     oscposhi[nvoice]&=OSCIL_SIZE-1;
  782.     };
  783. };
  784.  
  785.  
  786. /*Calculeaza Oscilatorul cu PITCH MODULATION*/
  787. inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice){    
  788. //TODO
  789. };
  790.  
  791. /*
  792.  * Computes the Noise 
  793.  */
  794. inline void ADnote::ComputeVoiceNoise(int nvoice){    
  795.     for (int i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=RND*2.0-1.0;
  796. };
  797.  
  798.  
  799.  
  800. /*
  801.  * Compute the ADnote samples 
  802.  * Returns 0 if the note is finished
  803.  */
  804. int ADnote::noteout(REALTYPE *outl,REALTYPE *outr){
  805.   int i,nvoice;
  806.     
  807.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  808.     outl[i]=denormalkillbuf[i];
  809.     outr[i]=denormalkillbuf[i];
  810.   };
  811.  
  812.   if (NoteEnabled==OFF) return(0);
  813.  
  814.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  815.     bypassl[i]=0.0;
  816.     bypassr[i]=0.0;
  817.   };
  818.   
  819.   computecurrentparameters();    
  820.  
  821.   for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  822.     if ((NoteVoicePar[nvoice].Enabled!=ON) || (NoteVoicePar[nvoice].DelayTicks>0)) continue;    
  823.     if (NoteVoicePar[nvoice].noisetype==0){//voice mode=sound
  824.         switch (NoteVoicePar[nvoice].FMEnabled){
  825.         case MORPH:ComputeVoiceOscillatorMorph(nvoice);break;
  826.         case RING_MOD:ComputeVoiceOscillatorRingModulation(nvoice);break;
  827.         case PHASE_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,0);break;
  828.         case FREQ_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,1);break;
  829.         //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break;
  830.         default:ComputeVoiceOscillator_LinearInterpolation(nvoice);
  831.         //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
  832.                 
  833.         };
  834.     } else ComputeVoiceNoise(nvoice);
  835.     // Voice Processing
  836.     
  837.      // Amplitude
  838.      if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])){
  839.           int rest=SOUND_BUFFER_SIZE;
  840.           //test if the amplitude if raising and the difference is high
  841.       if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)){
  842.         rest=10;
  843.         if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
  844.         for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) tmpwave[i]*=oldamplitude[nvoice];
  845.       };
  846.           // Amplitude interpolation
  847.           for (i=0;i<rest;i++){
  848.         tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(oldamplitude[nvoice]
  849.          ,newamplitude[nvoice],i,rest);
  850.       };
  851.     } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=newamplitude[nvoice];
  852.  
  853.      // Fade in
  854.       if (firsttick[nvoice]!=0){
  855.           fadein(&tmpwave[0]);
  856.           firsttick[nvoice]=0;
  857.       };
  858.  
  859.  
  860.      // Filter
  861.      if (NoteVoicePar[nvoice].VoiceFilter!=NULL) NoteVoicePar[nvoice].VoiceFilter->filterout(&tmpwave[0]);
  862.  
  863.     //check if the amplitude envelope is finished, if yes, the voice will be fadeout
  864.       if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) {
  865.     if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0)
  866.         for (i=0;i<SOUND_BUFFER_SIZE;i++) 
  867.                tmpwave[i]*=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
  868.     //the voice is killed later
  869.       };
  870.     
  871.  
  872.      // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
  873.      if (NoteVoicePar[nvoice].VoiceOut!=NULL) 
  874.     for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwave[i];
  875.  
  876.  
  877.      // Add the voice that do not bypass the filter to out
  878.       if (NoteVoicePar[nvoice].filterbypass==0){//no bypass
  879.           if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
  880.           else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
  881.             outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
  882.             outr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
  883.            };
  884.       } else {//bypass the filter
  885.           if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
  886.           else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
  887.             bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
  888.             bypassr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
  889.            };            
  890.       };
  891.     // chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
  892.       if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) {
  893.          if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) KillVoice(nvoice);
  894.      };
  895.   };
  896.  
  897.  
  898.   //Processing Global parameters
  899.   NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); 
  900.  
  901.   if (stereo==0) {
  902.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {//set the right channel=left channel
  903.         outr[i]=outl[i];
  904.         bypassr[i]=bypassl[i];
  905.     } 
  906.   } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); 
  907.   
  908.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  909.     outl[i]+=bypassl[i];
  910.     outr[i]+=bypassr[i];
  911.   };
  912.   
  913.   if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)){
  914.     // Amplitude Interpolation
  915.         for (i=0;i<SOUND_BUFFER_SIZE;i++){
  916.        REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude
  917.               ,globalnewamplitude,i,SOUND_BUFFER_SIZE);
  918.        outl[i]*=tmpvol*NoteGlobalPar.Panning;
  919.        outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); 
  920.         };
  921.   } else { 
  922.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  923.         outl[i]*=globalnewamplitude*NoteGlobalPar.Panning;
  924.         outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning);
  925.     };
  926.   };
  927.  
  928.  //Apply the punch
  929.  if (NoteGlobalPar.Punch.Enabled!=0){
  930.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  931.     REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0;
  932.     outl[i]*=punchamp;
  933.     outr[i]*=punchamp;
  934.     NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt;
  935.     if (NoteGlobalPar.Punch.t<0.0) {
  936.         NoteGlobalPar.Punch.Enabled=0;
  937.         break;
  938.     };
  939.     }; 
  940.  };
  941.       
  942.  // Check if the global amplitude is finished. 
  943.  // If it does, disable the note     
  944.  if (NoteGlobalPar.AmpEnvelope->finished()!=0) {
  945.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out
  946.         REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
  947.         outl[i]*=tmp;
  948.         outr[i]*=tmp;
  949.         };
  950.         KillNote(); 
  951.  };
  952.  return(1);
  953. };
  954.  
  955.  
  956. /*
  957.  * Relase the key (NoteOff)
  958.  */
  959. void ADnote::relasekey(){
  960. int nvoice;
  961.   for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  962.     if (NoteVoicePar[nvoice].Enabled==0) continue;
  963.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) NoteVoicePar[nvoice].AmpEnvelope->relasekey(); 
  964.     if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); 
  965.     if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); 
  966.     if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); 
  967.     if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); 
  968.   };
  969.   NoteGlobalPar.FreqEnvelope->relasekey();
  970.   NoteGlobalPar.FilterEnvelope->relasekey();
  971.   NoteGlobalPar.AmpEnvelope->relasekey();
  972.  
  973. };
  974.  
  975. /*
  976.  * Check if the note is finished
  977.  */
  978. int ADnote::finished(){
  979.     if (NoteEnabled==ON) return(0);
  980.     else return(1);
  981. };
  982.  
  983.  
  984.  
  985.